package com.transfiguro.converters;

import com.transfiguro.datamodel.csmodels.CSClassModel;
import com.transfiguro.datamodel.javamodels.ClassModel;
import com.transfiguro.exceptions.ConversionFailedException;
import com.transfiguro.utilities.FileUtilities;
import com.transfiguro.utilities.MappingXMLParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;

import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Modifier;

/**
 * An implementation of {@link Converter}. This class provides methods for converting
 * a {@link ClassModel} to {@link CSClassModel}. It converts the basic parameters of the class
 * like <code>className</code>, <code>accessModifier</code>, etc.
 */
public class BaseClassConverter implements Converter {
    private final Logger logger = LoggerFactory.getLogger(BaseClassConverter.class);

    private CSClassModel csClassModel;
    private ClassModel classModel;
    private File classXMLMapping;
    private static MappingXMLParser xmlParser;

    /**
     * Constructor
     *
     * @param model  The <code>classModel</code> to be converted
     */
    public BaseClassConverter(final ClassModel model) {
        csClassModel = new CSClassModel();
        classModel = model;
        init();
    }

    /**
     * Initializer for various private variables
     */
    public void init() {
        final ClassPathResource resource = new ClassPathResource("mappingxmls/ClassMapping.xml");
        final InputStream stream = ClassLoader.getSystemResourceAsStream("mappingxmls/ClassMapping.xml");
        final File tempFile = new File(".", "ClassMapping.xml");
        FileUtilities.writeTempFile(stream, tempFile);
        classXMLMapping = tempFile;
        xmlParser = new MappingXMLParser(classXMLMapping);
    }

    /**
     * This method converts the given <code>ClassModel</code> to a <code>CSClassModel</code>
     *
     * @return  <tt>True</tt> if conversion succeeded
     * @throws ConversionFailedException  when there is a problem in conversion
     */
    public boolean convert() throws ConversionFailedException {
        boolean result = true;
        csClassModel.setClassName(classModel.getClassName());
        if (!Modifier.toString(classModel.getAccessModifier()).equals("")) {
            StringBuilder modifier = new StringBuilder();
            for (final String mod : Modifier.toString(classModel.getAccessModifier()).split(" "))
                if (xmlParser.requiresConversion("accessModifier", mod.trim())) {
                    modifier.append(xmlParser.getTo("accessModifier", mod)).append(" ");
                } else {
                    modifier.append(mod).append(" ");
                }
            csClassModel.setAccessModifier(modifier.toString().trim());
        }
        csClassModel.setClassType(classModel.getClassType());
        return result;
    }

    /**
     * Getter for <code>csClassModel</code>
     *
     * @return  The <code>csClassModel</code> which has been
     *         created by converting the given <code>ClassModel</code>
     */
    public CSClassModel getCsClassModel() {
        return csClassModel;
    }

}
